﻿using CustomPixelShaderEffect.AttributeUsageFloder;
using CustomPixelShaderEffect.UlitFolder;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Effects;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Media.Imaging;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.Storage.Streams;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace CustomPixelShaderEffect.views
{
    [PageTypeAttribute("阈值效果")]
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class ThresholdEffectPage : Page
    {
        PixelShaderEffect effect;
        CanvasBitmap bitmap;
        public ThresholdEffectPage()
        {
            this.InitializeComponent();
            Init();
        }

        void Init()
        {
            canvas.CreateResources += async (s, e) =>
             {
                 //获取着色器二进制文件
                 StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Shaders/ThresholdEffect.bin"));
                 IBuffer buffer = await FileIO.ReadBufferAsync(file);
                 //转换成字节数组
                 var bytes = buffer.ToArray();
                 //用 字节数组 初始化一个 PixelShaderEffect 对象；
                 effect = new PixelShaderEffect(bytes);

             };

            //选择图片
            selectPicture.Click += async (s, e) =>
            {
                var file = await Ulit.SelectFileAsync(new List<string> { ".png", ".jpg" });
                if (file == null)
                    bitmap = null;
                else
                    bitmap = await CanvasBitmap.LoadAsync(canvas.Device, await file.OpenAsync(FileAccessMode.Read));
                canvas.Invalidate();
            };

            canvas.Draw += (s, e) =>
            {
                //绘制黑白网格
                Win2dUlit.DrawGridGraphics(e.DrawingSession, 100);
                //判断effect 和位图是否为空
                if (effect == null || bitmap == null)
                    return;
                var element = (FrameworkElement)s;
                float effectWidth = (float)element.ActualWidth;
                float effectHeight = (float)element.ActualHeight * 0.7f;
                float previewWidth = effectWidth;
                float previewHeight = (float)element.ActualHeight * 0.3f;
                //绘制原图
                var previewTran = Win2dUlit.CalcutateImageCenteredTransform(previewWidth, previewHeight, bitmap.Size.Width, bitmap.Size.Height);
                previewTran.Source = bitmap;
                e.DrawingSession.DrawImage(previewTran, 0, effectHeight);

                //颜色将0~255 转换成0~1 因为hlsl里面的颜色是0~1范围的并且是float类型，所以这里需要将每个颜色的分量除以255
                Vector4 startColor = new Vector4(cp1.Color.R / 255f, cp1.Color.G / 255f, cp1.Color.B / 255f, 1f);
                Vector4 endColor = new Vector4(cp2.Color.R / 255f, cp2.Color.G / 255f, cp2.Color.B / 255f, 1f);
                //通过键值对的形式设置属性传递到着色器里面
                effect.Properties["threshold"] = (float)threshold.Value;
                effect.Properties["startColor"] = startColor;
                effect.Properties["endColor"] = endColor;
                effect.Source1 = bitmap;

                //绘制效果图
                var effectTran = Win2dUlit.CalcutateImageCenteredTransform(effectWidth, effectHeight, bitmap.Size.Width, bitmap.Size.Height);
                effectTran.Source = effect;
                e.DrawingSession.DrawImage(effectTran);
            };

            threshold.ValueChanged += (s, e) => canvas.Invalidate();
            //这里遇到问题了 说找不到 WinRT.ObjectReferenceValue ABI.Windows.Foundation.TypedEventHandler`2.CreateMarshaler2(Windows.Foundation.TypedEventHandler`2<!0,!1>)'。”
            //cp1.ColorChanged += (s, e) =>
            //{
            //    //if (canvas.IsLoaded)
            //    //    canvas.Invalidate();
            //};
            //cp2.ColorChanged += (s, e) =>
            //{
            //    //if (canvas.IsLoaded)
            //    //    canvas.Invalidate();
            //};

        }
    }
}
